import json
from typing import Dict, Any, Optional, List
from .base import BaseTest
from .data_manager import TestDataManager
from .logger import test_logger

class APITest(BaseTest):
    """API测试基类"""
    
    def __init__(self, base_url: str):
        super().__init__(base_url)
        self.data_manager = TestDataManager()
        
    def setup_test_data(self, data: Dict[str, Any]):
        """设置测试数据
        
        Args:
            data: 测试数据，包含setup和teardown两部分
        """
        if "setup" in data:
            for item in data["setup"]:
                if "type" in item and "data" in item:
                    self._setup_item(item["type"], item["data"])
                    
    def teardown_test_data(self, data: Dict[str, Any]):
        """清理测试数据
        
        Args:
            data: 测试数据，包含setup和teardown两部分
        """
        if "teardown" in data:
            for item in data["teardown"]:
                if "type" in item and "data" in item:
                    self._teardown_item(item["type"], item["data"])
                    
    def _setup_item(self, item_type: str, data: Dict[str, Any]):
        """设置单个测试数据项
        
        Args:
            item_type: 数据类型，如user、item等
            data: 测试数据
        """
        endpoint = self._get_endpoint(item_type)
        if endpoint:
            response = self.execute_request(
                "POST",
                endpoint,
                headers=self.auth_headers,
                json=data
            )
            if response.status_code in (200, 201):
                item_id = response.json().get("id")
                if item_id:
                    self.data_manager.set_data(f"{item_type}_{item_id}", item_id)
                    self.logger.info(f"Created {item_type} with ID: {item_id}")
                    
    def _teardown_item(self, item_type: str, data: Dict[str, Any]):
        """清理单个测试数据项
        
        Args:
            item_type: 数据类型，如user、item等
            data: 测试数据
        """
        endpoint = self._get_endpoint(item_type)
        if endpoint and "id" in data:
            self.execute_request(
                "DELETE",
                f"{endpoint}/{data['id']}",
                headers=self.auth_headers
            )
            
    def _get_endpoint(self, item_type: str) -> Optional[str]:
        """获取数据类型的API端点
        
        Args:
            item_type: 数据类型
            
        Returns:
            API端点路径
        """
        endpoints = {
            "user": "/users",
            "item": "/items",
            "order": "/orders",
            "category": "/categories"
        }
        return endpoints.get(item_type)
        
    def execute_test_case(self, test_case: Dict[str, Any]):
        """执行测试用例
        
        Args:
            test_case: 测试用例数据
        """
        # 准备测试数据
        if "data" in test_case:
            self.setup_test_data(test_case["data"])
            
        try:
            # 执行测试步骤
            for step in test_case.get("steps", []):
                self._execute_step(step)
        finally:
            # 清理测试数据
            if "data" in test_case:
                self.teardown_test_data(test_case["data"])
                
    def _execute_step(self, step: Dict[str, Any]):
        """执行测试步骤
        
        Args:
            step: 测试步骤数据
        """
        if "request" not in step or "expected" not in step:
            return
            
        request = step["request"]
        expected = step["expected"]
        
        # 处理请求数据中的变量
        if "body" in request:
            request["body"] = self._process_variables(request["body"])
            
        # 执行请求
        response = self.execute_request(
            request["method"],
            request["endpoint"],
            headers=self.auth_headers,
            json=request.get("body")
        )
        
        # 验证响应
        self.validate_response(
            response,
            expected["status_code"],
            expected.get("response")
        )
        
    def _process_variables(self, data: Any) -> Any:
        """处理数据中的变量
        
        Args:
            data: 包含变量的数据
            
        Returns:
            处理后的数据
        """
        if isinstance(data, dict):
            return {k: self._process_variables(v) for k, v in data.items()}
        elif isinstance(data, list):
            return [self._process_variables(item) for item in data]
        elif isinstance(data, str) and data.startswith("{") and data.endswith("}"):
            var_name = data[1:-1]
            return self.data_manager.get_data(var_name)
        return data 